package com.douqu.game.core.entity.world;

import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.core.config.hegemony.HegemonyRankRewardGroupConfig;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.ext.data.BaseData;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.factory.FunctionFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.CoreUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: Bean
 * @Description:
 * @Date: 2018-02-06 10:53
 */
public class WorldRankData extends BaseData {

    /**
     * 所有排行榜基本数据(只存唯一标识和排行值)
     */
    private Map<Integer, List<WorldRankBean>> rankMap = new ConcurrentHashMap<>();

    /**
     * 排行活动的类型
     */
    private Map<Integer, Integer> rankStatus = new HashMap<>();

    /**
     * 排行奖励分组
     * 1.争霸赛排行存上周前十平均等级 没有的话按第一个group计算
     */
    private Map<Integer, Integer> rewardGroupMap = new HashMap<>();

    @Override
    public void init() {

    }

    @Override
    public void checkInit() {

    }

    @Override
    public void reset() {
        rankMap.put(SGCommonProto.E_RANK_TYPE.RANK_TYPE_WORLDMAP_VALUE,new CopyOnWriteArrayList<>());
    }

    @Override
    public void checkReset() {

    }

    @Override
    public void writeTo(ByteBuffer buffer)
    {
        buffer.writeByte(rankMap.size());

        for(Map.Entry<Integer, List<WorldRankBean>> entry : rankMap.entrySet())
        {
            buffer.writeShort(entry.getValue().size());

            for(WorldRankBean bean : entry.getValue())
            {
                bean.writeTo(buffer);
            }

            buffer.writeByte(entry.getKey());
        }

        buffer.writeByte(rankStatus.size());
        for (Map.Entry<Integer,Integer> entry:rankStatus.entrySet()){
            buffer.writeByte(entry.getKey());
            buffer.writeByte(entry.getValue());
        }

        buffer.writeByte(rewardGroupMap.size());
        for (Map.Entry<Integer,Integer> entry:rewardGroupMap.entrySet()){
            buffer.writeByte(entry.getKey());
            buffer.writeShort(entry.getValue());
        }
    }

    @Override
    public void loadFrom(ByteBuffer buffer)
    {
        int len = buffer.readByte();
        int size = 0;
        WorldRankBean bean = null;
        List<WorldRankBean> list = null;
        for(int i = 0; i < len; i++)
        {
            size = buffer.readShort();
            list = new CopyOnWriteArrayList<>();
            for(int j = 0; j < size; j++)
            {
                bean = new WorldRankBean();
                bean.loadFrom(buffer);
                list.add(bean);
            }
            rankMap.put(buffer.readByte(), list);
        }

        len = buffer.readByte();
        for (int i = 0; i < len;i ++){
            rankStatus.put(buffer.readByte(),buffer.readByte());
        }

        len = buffer.readByte();
        for (int i = 0;i < len;i ++){
            rewardGroupMap.put(buffer.readByte(),buffer.readShort());
        }
    }



    public void removePlayer(Player player)
    {
        for(List<WorldRankBean> list : rankMap.values())
        {
            for(WorldRankBean bean : list)
            {
                if(bean.getObjectIndex().equals(player.getObjectIndex()))
                {
                    list.remove(bean);
                    break;
                }
            }
        }
    }

//    /**
//     * 竞技场更新战力
//     * @param playerIndex
//     * @param value
//     */
//    public void updateRankValue(SGCommonProto.E_RANK_TYPE rankType, String playerIndex, int value)
//    {
//        List<WorldRankBean> rankList = rankMap.get(rankType.getNumber());
//        if(rankList == null)
//            return;
//
//        WorldRankBean rankPlayerBase = new WorldRankBean(playerIndex, value);
//        int index = rankList.lastIndexOf(rankPlayerBase);
//        if(index != -1)
//        {
//            rankPlayerBase = rankList.get(index);
//            rankPlayerBase.setValue(value);
//        }
//    }

    /**
     * 把当前的排行赋值给旧的 并且清除当前的
     * 这里不能直接clear
     */
    public void clearRank(SGCommonProto.E_RANK_TYPE rankType){
        rankMap.put(rankType.getNumber(),new CopyOnWriteArrayList<>());
    }

    public boolean updateRankInfo(SGCommonProto.E_RANK_TYPE rankType, String playerIndex, int value)
    {
        return updateRankInfo(rankType,playerIndex,(long)value);
    }

    public boolean updateRankInfo(SGCommonProto.E_RANK_TYPE rankType, String playerIndex, long value)
    {
        List<WorldRankBean> rankList = getRankList(rankType);

        WorldRankBean rankPlayerBase = new WorldRankBean(playerIndex, value);
        int index = rankList.lastIndexOf(rankPlayerBase);
        boolean isNew = false;
        if(index == -1)
        {
            rankList.add(rankPlayerBase);
            isNew = true;
        }
        else
        {
            rankPlayerBase = rankList.get(index);
            //如果是boss战排行 值是累加计算的
            if (rankType == SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS){
                if (value <= 0)
                    return false;

                rankPlayerBase.addValue(value);

            }else{
                if(value > rankPlayerBase.getValue())
                    rankPlayerBase.setValue(value);
                else
                    return false;
            }
            //更新时间
            int lastUpdateTime = (int) (DataFactory.currentTime/1000);
            rankPlayerBase.setLastUpdateTime(lastUpdateTime);
        }

        rankList.sort(new Comparator<WorldRankBean>() {
            @Override
            public int compare(WorldRankBean o1, WorldRankBean o2) {
                if(o1.getValue() != o2.getValue())
                    return new Long(o2.getValue()).compareTo(o1.getValue());//从大到小排序
                else
                    return new Integer(o1.getCreateTime()).compareTo(o2.getCreateTime());//值一样的时候按时间先后
            }
        });

        int size = rankList.size();
        rankPlayerBase = rankList.get(size-1);
        if (rankType != SGCommonProto.E_RANK_TYPE.RANK_TYPE_WORLDMAP
                && rankType != SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPCURRWEEK
                && rankType != SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS){
            //其他排行一共只排前100
            if(isNew && size > ConstantFactory.RANK_COUNT)
            {
                boolean result = !rankPlayerBase.getObjectIndex().equals(playerIndex);

                rankList.remove(rankPlayerBase);

                return result;
            }
        }
        return true;
    }


    public List<WorldRankBean> getRankList(SGCommonProto.E_RANK_TYPE rankType)
    {
        List<WorldRankBean> list = rankMap.get(rankType.getNumber());
        if(list == null)
        {
            list = new CopyOnWriteArrayList<>();
            rankMap.put(rankType.getNumber(), list);
            rankStatus.put(rankType.getNumber(),SGCommonProto.E_MAP_HEGEMONY_RANK_TYPE.WORLD_MAP_RANk_CURRENT_DRESS.getNumber());
        }
        return list;
    }

    /** 获取排行bean */
    public WorldRankBean getRankByIndex(SGCommonProto.E_RANK_TYPE rankType,int index){
        List<WorldRankBean> list = rankMap.get(rankType.getNumber());
        if (list.size() < (index + 1))
            return null;
        return list.get(index);
    }

    public List<WorldRankBean> getRankList(SGCommonProto.E_RANK_TYPE rankType,Integer maxValue){
        if (rankMap.get(rankType.getNumber()) == null){
            return null;
        }
        maxValue = maxValue > rankMap.get(rankType.getNumber()).size()?rankMap.get(rankType.getNumber()).size():maxValue;
        List<WorldRankBean> list = rankMap.get(rankType.getNumber()).subList(0,maxValue);
        if (list == null){
            list = new CopyOnWriteArrayList<>();
        }
        return list;
    }

    /**
     * 获得某个排行榜某个区间的list
     * @param rankMap
     * @param rankType
     * @param value1
     * @param value2
     * @return
     */
    public List<WorldRankBean> getRankList(Map<Integer, List<WorldRankBean>> rankMap,SGCommonProto.E_RANK_TYPE rankType,Integer value1,Integer value2){
        if (rankMap.get(rankType.getNumber()) == null){
            return new ArrayList<>();
        }
        int maxValue = value1;
        int minValue = value2;
        if (value1 < value2){
             maxValue = value2;
             minValue = value1;
        }
        maxValue = maxValue > rankMap.get(rankType.getNumber()).size() ? rankMap.get(rankType.getNumber()).size() : maxValue;
        if (maxValue< minValue){
            return  new ArrayList<>();
        }
        List<WorldRankBean> list = rankMap.get(rankType.getNumber()).subList(minValue, maxValue);
        if (list == null) {
            list =  new ArrayList<>();
        }
        return list;
    }

    /**
     * 获取玩家的排行
     * @param player
     * @param type
     * @return
     */
    public int getRankByPlayer(Player player,SGCommonProto.E_RANK_TYPE type){
        int functionId = 0;
        if (type == SGCommonProto.E_RANK_TYPE.RANK_TYPE_ARENA){
            //竞技场
            functionId = FunctionFactory.UNLOCK_COMPETITIVE_SYSTEM;
        }else if (type == SGCommonProto.E_RANK_TYPE.RANK_TYPE_EXPEDITION){
            //远征
            functionId = FunctionFactory.UNLOCK_EXPEDITION_SYSTEM;
        }else if (type == SGCommonProto.E_RANK_TYPE.RANK_TYPE_CAMP){
            //阵营战
            functionId = FunctionFactory.CAMP_BATTLE;
        }else if (type == SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPLASTWEEK || type == SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPCURRWEEK){
            //阵营战
            functionId = FunctionFactory.WORLD_MAP_HEGEMONY;
        }
        if (functionId < FunctionFactory.RANK_SYSTEM)
            functionId = FunctionFactory.RANK_SYSTEM;

        //未开启排行
        if(!CoreUtils.isFunctionUnLock(functionId, player))
            return 0;
        List<WorldRankBean> list = getRankList(type);
        //正序的玩家肯定是玩的比较多的玩家
        for (int i = 0;i < list.size(); i ++){
            if (list.get(i).getObjectIndex().equals(player.getObjectIndex())){
                //当前玩家的排行
                return i+1;
            }
        }
        return 0;
    }

    public Map<Integer, List<WorldRankBean>> getRankMap() {
        return rankMap;
    }

    public void clear(int rankType)
    {
        if(rankType == 0)
            rankMap.clear();
        else
        {
            if(rankMap.get(rankType) != null)
            {
                rankMap.get(rankType).clear();
            }
        }
    }

    public SGCommonProto.E_MAP_HEGEMONY_RANK_TYPE getRankStatus(SGCommonProto.E_RANK_TYPE type){
        Integer status = rankStatus.get(type.getNumber());
        if (status == null){
            synchronized (rankStatus){
                rankStatus.put(type.getNumber(),SGCommonProto.E_MAP_HEGEMONY_RANK_TYPE.WORLD_MAP_RANk_CURRENT_DRESS_VALUE);
                status = rankStatus.get(type.getNumber());
            }
        }
        return SGCommonProto.E_MAP_HEGEMONY_RANK_TYPE.forNumber(status);
    }

    public HegemonyRankRewardGroupConfig getRewardGroup(SGCommonProto.E_RANK_TYPE type){

        HegemonyRankRewardGroupConfig groupConfig = HegemonyRankRewardGroupConfig.getConfigByLv(getRankStatus(type),
                rewardGroupMap.get(type.getNumber()));

        return groupConfig;
    }

    public Map<Integer, Integer> getRewardGroupMap() {
        return rewardGroupMap;
    }

    public void setRewardGroupMap(Map<Integer, Integer> rewardGroupMap) {
        this.rewardGroupMap = rewardGroupMap;
    }

    public Map<Integer, Integer> getRankStatus() {
        return rankStatus;
    }

    public void setRankStatus(Map<Integer, Integer> rankStatus) {
        this.rankStatus = rankStatus;
    }
}
